<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, toValue } from 'vue'
import * as echarts from 'echarts/core'
import { GeoComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
// import { Bar3DChart, Map3DChart } from 'echarts-gl/charts'
// import { Grid3DComponent } from 'echarts-gl/components'
import 'echarts-gl'

import useElementResize from './useElementResize'

import map321000 from './321000.json'
import map321002 from './321002.json'
import map321003 from './321003.json'
import map321012 from './321012.json'
import map321023 from './321023.json'
import map321081 from './321081.json'
import map321084 from './321084.json'

import { MESSAGE_EVENT_TYPE, sendMessage } from '@/api'
import { screenAreaList } from '@/api/screen'

echarts.use([
  TooltipComponent,
  GeoComponent,
  CanvasRenderer,
  // Bar3DChart,
  // Map3DChart,
  // Grid3DComponent
])

const geoJSON = {
  321000: map321000,
  321002: map321002,
  321003: map321003,
  321012: map321012,
  321023: map321023,
  321081: map321081,
  321084: map321084,
} as const

type KeyGeoJSON = keyof typeof geoJSON

const colors = {
  321002: '#af8956',
  321003: '#5a7cad',
  321012: '#d394c2',
  321023: '#7ccbc2',
  321081: '#baaf6c',
  321084: '#32766d',
  360123: '#517637',
  360124: '#3f562e',
} as const
type KeyColor = keyof typeof colors

const viewControl = {
  alpha: 90,
  beta: 0,
  autoRotate: false,
  distance: 415,
  center: [0, -10, 20],
  zoomSensitivity: 0,
}

let chart: echarts.ECharts

const containerRef = ref<HTMLElement | null>(null)
const map = ref('321000')

// 区域浮窗数据
const areaData: { [key: string]: number | string } = shallowReactive({
  321000: '-',
  321012: '-',
  321023: '-',
  321001: '-',
  321084: '-',
  321071: '-',
  321081: '-',
  321002: '-',
  321003: '-',
})

const defaultNumber = inject<(x: any) => string>('defaultNumber')

const chartOption = computed(() => {
  const mapValue = toValue(map) as unknown as KeyGeoJSON
  const regions = geoJSON[mapValue].features
  return {
    tooltip: {
      show: true,
      backgroundColor: 'rgb(4, 56, 141)',
      borderColor: '#507ab0',
      extraCssText: 'z-index: 3000',
      textStyle: {
        color: '#f9f9f9',
      },
      formatter(params: any) {
        // console.log(params)
        const adcode = params.data.value
        const value = defaultNumber ? defaultNumber(areaData[adcode]) : areaData[adcode]
        return `
              <div class="geo3d-tooltip">${params.data.name}</div>
              <table style="border-collapse: separate;">
                <thead>
                  <tr>
                    <th>名称</th>
                    <th style="padding-left: 10px;padding-right:10px;width: 120px;text-align:center;">数值</th>
                    <th>单位</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td>综合能源消费量</td>
                    <td style="text-align:center;">${value}</td>
                    <td>吨标准煤</td>
                  </tr>
                </tbody>
              </table>
            `
      },
    },
    geo3D: {
      type: 'map3D',
      map: mapValue,
      boxHeight: 7,
      regionHeight: 2,
      itemStyle: {
        opacity: 0,
      },
      viewControl,
      silent: true,
      zlevel: 0,
    },
    series: [
      {
        type: 'map3D',
        map: mapValue,
        boxHeight: 7,
        regionHeight: 2,
        viewControl,
        // silent: true,
        emphasis: {
          label: {
            show: true,
            color: '#ffffff',
            fontWeight: 'bold',
            fontSize: 15,
          },
          // itemStyle: {
          //   opacity: 1,
          //   color: 'rgb(14,131,216)'
          // }
        },
        data: regions.map(v => ({
          region: v.properties,
          name: v.properties.name,
          value: v.properties.adcode,
          label: {
            show: true,
            distance: 5,
            color: '#ffffff',
            fontWeight: 'bold',
            fontSize: 15,
          },
          // value: v.properties.adcode,
          itemStyle: {
            color: colors[v.properties.adcode as KeyColor],
          },
        })),
        zlevel: 2,
      },
    ],
  }
})

function registerMaps() {
  for (const map in geoJSON) {
    echarts.registerMap(map, geoJSON[map as unknown as keyof typeof geoJSON] as any)
  }
}
function renderMap() {
  if (!chart) {
    chart = echarts.init(toValue(containerRef))
  }
  chart.setOption(toValue(chartOption))
}
function init() {
  registerMaps()
  renderMap()
}

const resizeRef = ref<HTMLElement>()
function resizeHandler() {
  chart.resize({
    animation: {
      duration: 1000,
    },
  })
}

function clickHandler(e: any) {
  // console.log(e)
  let type
  const seriesType = e.seriesType
  let id
  if (seriesType === 'map3D') {
    id = e.value
    type = 'districtCode'
  }
  else if (seriesType === 'bar3D') {
    id = e.value[e.value.length - 1]
    type = 'enterpriseCode'
  }
  // console.log(type, id);
  if (!id || !type)
    return
  sendMessage({
    key: type,
    value: id,
  }, MESSAGE_EVENT_TYPE.PAGE_NAVIGATE)
}

function bindMapClickEvent() {
  chart.on('click', clickHandler)
}
function unbindClickEvent() {
  chart.off('click', clickHandler)
}

// 获取区域浮窗数据
async function getAreaData() {
  try {
    const { data } = await screenAreaList()
    Object.assign(areaData, data)
  }
  catch (error) {
    console.log(error)
  }
}

let removeAllListeners: () => void
onMounted(() => {
  init()
  getAreaData()
  if (resizeRef.value) {
    removeAllListeners = useElementResize(() => resizeRef.value!, resizeHandler)
  }
  bindMapClickEvent()
})
onBeforeUnmount(() => {
  removeAllListeners?.()
  unbindClickEvent()
})
</script>

<template>
  <div ref="resizeRef" class="geo-map">
    <div ref="containerRef" style="width: 100%; height: 100%" />
  </div>
</template>
